package com.mallcai.bigdata.ladon.service.report.impl.handler;

import com.cake.bigdata.starter.exception.category.BusinessException;
import com.mallcai.bigdata.ladon.client.vo.ReportDataVO;
import com.mallcai.bigdata.ladon.datasource.RunInfoResult;
import com.mallcai.bigdata.ladon.dpl.entity.report.Report;
import com.mallcai.bigdata.ladon.service.report.IReportQueryStatisticService;
import com.mallcai.bigdata.ladon.service.report.impl.ReportQueryConstants;
import com.mallcai.bigdata.ladon.service.report.impl.ReportQueryContext;
import com.mallcai.bigdata.ladon.service.report.impl.ReportStatisticDTO;
import com.mallcai.bigdata.ladon.service.system.IEnvService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @author feixy
 * @version 1.0
 * @date 2019-07-19 21:00
 */
@Slf4j
@Component
@Order(2540)
public class ReportAutoSwitchFlowHandler extends AbstractReportQueryBothHandler {

    private static int                          ERROR_CALL_LIMIT = 10;
    @Autowired
    private        IReportQueryStatisticService iReportQueryStatisticService;

    @Autowired
    private IEnvService iEnvService;

    @Override
    public void preInternal(ReportQueryContext context) {
        if(!iEnvService.isProduct()){
            return;
        }
        Report report = context.getReport();
        boolean isFlowOff = context.getInnerParam(ReportQueryConstants.KEY_IS_FLOW_OFF);
        if(!isFlowOff){
            ReportStatisticDTO statistic = iReportQueryStatisticService.getStatistic(report.getCode());
            if (statistic.getErrorCall() > ERROR_CALL_LIMIT){
                log.warn("报表[code:{}]最近发生错误次数过多,已被自动限流",context.getReportCode());
               context.putInnerParam(ReportQueryConstants.KEY_IS_FLOW_OFF, true);
            }
        }
    }

    @Override
    protected void postInternal(ReportQueryContext context) {
        if(!iEnvService.isProduct()){
            return;
        }
        boolean isFlowOff = context.getInnerParam(ReportQueryConstants.KEY_IS_FLOW_OFF);
        if (!isFlowOff){
            RunInfoResult<ReportDataVO> result = context.getResult();
            if (result != null && result.getError() != null){
                ReportStatisticDTO statistic = iReportQueryStatisticService.getStatistic(context.getReportCode());
                if (isUnExpectedException(result.getError()) && statistic.getErrorCall() <= ERROR_CALL_LIMIT){
                    iReportQueryStatisticService.incErrorCall(context.getReport().getCode());
                }
            } else if(result != null){
                iReportQueryStatisticService.resetErrorCall(context.getReport().getCode());
            }
        }
    }

    private boolean isUnExpectedException(Exception error) {
        return error != null && !(error instanceof BusinessException);
    }
}
